package com.xiaohai.controller;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xiaohai.common.R;
import com.xiaohai.exception.CustomException;
import com.xiaohai.projo.*;
import com.xiaohai.projo.Class;
import com.xiaohai.projo.dto.ScoreDto;
import com.xiaohai.projo.excel.*;
import com.xiaohai.service.*;
import com.xiaohai.utils.ExcelListener;
import com.xiaohai.utils.ToPinyinUtil;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import net.sourceforge.pinyin4j.PinyinHelper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Objects;

/**
 * ClassName:TestController
 * Package:IntelliJ IDEA
 * Description:
 * Author 何诗海
 *
 * @Create 2024/3/5 18:44
 * @Version 1.0
 */

@Slf4j
@RestController
@RequestMapping("/excel")
public class ExcelController {
    @Autowired
    private ScoreService scoreService;

    @Autowired
    private TeacherService teacherService;

    @Autowired
    private ClassService classService;

    @Autowired
    private MajorService majorService;
    @Autowired
    private CourseService courseService;
    @Autowired
    private StudentService studentService;

    @GetMapping("/score")
    public void download(Integer identity, HttpServletResponse response, String account) throws IOException {
        List<ScoreDto> list = scoreService.exportList(identity, account);
        list.forEach(s -> {
            s.setTerm1(s.getTerm() == 1 ? "上学期" : "下学期");
            Integer grade = s.getGrade();
            String s1 = Integer.parseInt(s.getScore()) >= s.getMax() * 0.6 ? "及格" : "不及格";
            s.setState(s1);
            switch (grade) {
                case 1:
                    s.setGrade2("大一");
                    break;
                case 2:
                    s.setGrade2("大二");
                    break;
                case 3:
                    s.setGrade2("大三");
                    break;
                case 4:
                    s.setGrade2("大四");
                    break;
            }

        });
        // 这里注意 有同学反应使用swagger 会导致各种问题，请直接用浏览器或者用postman
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("分数", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        EasyExcel.write(response.getOutputStream(), ScoreDto.class).sheet("模板").doWrite(list);
    }

    @PostMapping("/class")
    public R<Object> aclass(MultipartFile file, String account) throws IOException {
        //创建一个监听器对象
        ExcelListener<Eclass> excelListener = new ExcelListener<>();
        //调用EasyExcel的api解析Excel
        EasyExcel.read(file.getInputStream(), Eclass.class, excelListener).sheet().doRead();
        //获取解析到的数据
        List<Eclass> eclassList = excelListener.getDatas();
        //遍历输出解析到数据
        eclassList.forEach(s -> {
            String name = s.getTeacherName();
            LambdaQueryWrapper<Teacher> teacherLambdaQueryWrapper = new LambdaQueryWrapper<>();
            teacherLambdaQueryWrapper.eq(name != null, Teacher::getName, name);
            Teacher teacher = teacherService.getOne(teacherLambdaQueryWrapper);
            if (Objects.isNull(teacher)) {
                throw new CustomException("导入失败，教师不存在");
            }
            s.setTeaId(teacher.getId());

            Class aClass = new Class();
            BeanUtils.copyProperties(s, aClass);
            classService.add(aClass, 5, account);
        });

        return R.success(null, "导入班级成功");
    }

    @PostMapping("/teacher")
    public R<Object> teacher(MultipartFile file) throws IOException {
        ExcelListener<ETeacher> excelListener = new ExcelListener<>();
        EasyExcel.read(file.getInputStream(), ETeacher.class, excelListener).sheet().doRead();
        List<ETeacher> teacherList = excelListener.getDatas();
        try {
            teacherList.forEach(t -> {
                String sex = t.getSex();
                t.setGender(sex.equals("男") ? 1 : 0);
                Teacher teacher = new Teacher();
                String account = ToPinyinUtil.toPinyin(t.getName());
                teacher.setAccount(account);
                String s = DigestUtils.md5DigestAsHex("123456".getBytes());
                teacher.setPassword(s);
                teacher.setIdentity(3);
                BeanUtils.copyProperties(t, teacher);
                teacherService.add(teacher);
            });
        } catch (Exception e) {
            throw new CustomException("导入教师失败");
        }

        return R.success(null, "导入教师成功");
    }

    @PostMapping("/major")
    public R<Object> major(MultipartFile file) throws IOException {
        ExcelListener<EMajor> excelListener = new ExcelListener<>();
        EasyExcel.read(file.getInputStream(), EMajor.class, excelListener).sheet().doRead();
        List<EMajor> majorList = excelListener.getDatas();
        try {
            majorList.forEach(m -> {
                Major major = new Major();
                BeanUtils.copyProperties(m, major);
                majorService.save(major);
            });
        } catch (Exception e) {
            throw new CustomException("导入专业失败");
        }
        return R.success(null, "导入专业成功");
    }

    @PostMapping("/course")
    public R<Object> course(MultipartFile file) throws IOException {
        ExcelListener<ECourse> excelListener = new ExcelListener<>();
        EasyExcel.read(file.getInputStream(), ECourse.class, excelListener).sheet().doRead();
        List<ECourse> courseList = excelListener.getDatas();
        courseList.forEach(c -> {
            Course course = new Course();
            String teacherName = c.getTeacherName();
            Teacher teacher = teacherService.getOne(new LambdaQueryWrapper<Teacher>().eq(teacherName != null, Teacher::getName, teacherName));
            if (Objects.isNull(teacher)) {
                throw new CustomException("导入失败，教师不存在");
            }
            course.setState(Objects.equals(c.getState(), "主修") ? 1 : Objects.equals(c.getState(), "选修") ? 2 : 3);
            course.setTeaId(teacher.getId());
            BeanUtils.copyProperties(c, course);
            courseService.add(course);
        });
        return R.success(null, "导入课程成功");
    }

    @PostMapping("/student")
    public R<Object> student(MultipartFile file) throws IOException {
        ExcelListener<EStudent> excelListener = new ExcelListener<>();
        EasyExcel.read(file.getInputStream(), EStudent.class, excelListener).sheet().doRead();
        List<EStudent> studentList = excelListener.getDatas();
        studentList.forEach(s -> {
            Student student = new Student();
            String majorName = s.getMajorName();
            String className = s.getClassName();
            Major major = majorService.getOne(new LambdaQueryWrapper<Major>().eq(majorName != null, Major::getName, majorName));
            Class aClass = classService.getOne(new LambdaQueryWrapper<Class>().eq(className != null, Class::getName, className));
            if (Objects.isNull(major)) {
                throw new CustomException("导入失败，专业不存在");
            }
            if (Objects.isNull(aClass)) {
                throw new CustomException("导入失败，班级不存在");
            }
            student.setMajorId(major.getId());
            student.setClassId(aClass.getId());
            String account = ToPinyinUtil.toPinyin(s.getName());
            String password = DigestUtils.md5DigestAsHex("123456".getBytes());
            student.setAccount(account);
            student.setPassword(password);
            student.setGender(Objects.equals(s.getSex(), "男") ? 1 : 0);
            student.setIdentity(2);
            BeanUtils.copyProperties(s, student);
            studentService.add(student);
        });
        return R.success(null, "导入学生成功");
    }

    @PostMapping("/score")
    public R<Object> score(MultipartFile file) throws IOException {
        ExcelListener<EScore> excelListener = new ExcelListener<>();
        EasyExcel.read(file.getInputStream(), EScore.class, excelListener).sheet().doRead();
        List<EScore> scoreList = excelListener.getDatas();
        scoreList.forEach(s -> {
            Score score = new Score();
            String studentName = s.getStudentName();
            String courseName = s.getCourseName();
            String teacherName = s.getTeacherName();
            String gradeName = s.getGradeName();
            String termName = s.getTermName();
            Student student = studentService.getOne(new LambdaQueryWrapper<Student>().eq(studentName != null, Student::getName, studentName));
            if (Objects.isNull(student)) {
                throw new CustomException("导出成绩失败，学生不存在");
            }
            Course course = courseService.getOne(new LambdaQueryWrapper<Course>().eq(courseName != null, Course::getName, courseName));
            if (Objects.isNull(course)) {
                throw new CustomException("导出成绩失败，课程不存在");
            }
            Teacher teacher = teacherService.getOne(new LambdaQueryWrapper<Teacher>().eq(teacherName != null, Teacher::getName, teacherName));
            if (Objects.isNull(teacher)) {
                throw new CustomException("导出成绩失败，教师不存在");
            }
            score.setCourceId(course.getId());
            score.setStuId(student.getId());
            score.setTeaId(teacher.getId());
            score.setTerm(Objects.equals(s.getTermName(), "上学期") ? 1 : 2);
            switch (s.getGradeName()) {
                case "大一":
                    score.setGrade(1);
                    break;
                case "大二":
                    score.setGrade(2);
                    break;
                case "大三":
                    score.setGrade(3);
                    break;
                case "大四":
                    score.setGrade(4);
                    break;
            }
            BeanUtils.copyProperties(s, score);
            scoreService.add(score);
        });
        return R.success(null, "导入成绩成功");
    }
}
